/*******************************************************************************
* Project: QSAR(Cute Software Architecture) 
*
* Copyright: Copyright(C) 2024 by YuetingBen, All Rights Reserved
*
* File name: NvmQueue.c
*
* Brief: ;
*
* Author: Yueting.Ben
*
* Module: Nvm
*
*******************************************************************************/

/** HEADER FILES **/
#include "NvmQueue.h"


/** MACRO DEFINITION **/


/** TYPEDEF DEFINITION **/


/** LOCAL DATA DECLARATION **/
Std_ReturnType NvM_QueuePush(
    NvM_BlockIdType BlockId,
    NvM_JobIdType JobId,
    NvMRamBlockDataAddressType RamAddress
);


/** GLOBAL DATA DECLARATION **/



/** LOCAL FUNCTION DECLARATION **/
static NvM_QueueType NvM_JobQueueTable[NVM_SIZE_JOB_QUEUE];


/** GLOBAL FUNCTION DECLARATION **/


/** LOCAL DATA **/
static NvM_QueueType NvM_JobQueueTable[NVM_SIZE_JOB_QUEUE] = {0u};

/** GLOBAL DATA **/


/** LOCAL FUNCTION **/


/** GLOBAL FUNCTION **/

/*******************************************************************************
* -Name            NvM_QueueInit
* -Brief           Build queue ring  
* -Details         None
* -Param[in]       None
* -Return          None          
*******************************************************************************/
Std_ReturnType NvM_QueueInit(
    void
)
{
    Std_ReturnType retVal = E_OK;

    NvM_QueueIndexType queueIndex = 0u;

    for(queueIndex = 0u; queueIndex < NVM_SIZE_JOB_QUEUE; queueIndex++)
    {
        if(0u == queueIndex)
        {
            /* First item, prev entry point to last item */
            NvM_JobQueueTable[queueIndex].PrevEntry = (NVM_SIZE_JOB_QUEUE - 1u);
            NvM_JobQueueTable[queueIndex].NextEntry = queueIndex + 1u;
        }
        else if((NVM_SIZE_JOB_QUEUE - 1u) == queueIndex)
        {
            /* Last item, next entry point to first item */
            NvM_JobQueueTable[queueIndex].PrevEntry = queueIndex - 1u;
            NvM_JobQueueTable[queueIndex].NextEntry = 0u;
        }
        else
        {
            NvM_JobQueueTable[queueIndex].PrevEntry = queueIndex - 1u;
            NvM_JobQueueTable[queueIndex].NextEntry = queueIndex + 1u;
        }

        NvM_JobQueueTable[queueIndex].QueueEmpty = SET;
    }

    CurrentQueue = NvM_JobQueueTable;


    return(retVal);
}


/*******************************************************************************
* -Name            NvM_QueueJob
* -Brief           Service to copy the data of the RAM block to its corresponding NV block 
* -Details         None
* -Param[in]       BlockId: The block identifier uniquely identifies one NVRAM block descriptor
* -Param[in]       NvM_DstPtr: Pointer to the RAM data block
* -Return          None          
*******************************************************************************/
Std_ReturnType NvM_QueueJob(
    NvM_BlockIdType BlockId,
    NvM_JobIdType JobId,
    NvMRamBlockDataAddressType RamAddress
)
{
    Std_ReturnType retVal = E_NOT_OK;

    retVal = NvM_QueuePush(BlockId, JobId, RamAddress);

    return(retVal);
}



/*******************************************************************************
* -Name            NvM_QueuePush
* -Brief           Add job to current queue, then current queue pointer to next one
* -Details         None
* -Param[in]       BlockId: The block identifier uniquely identifies one NVRAM block descriptor
* -Param[in]       JobId: Job Id
* -Param[in]       RamAddress: RamAddress
* -Return          None          
*******************************************************************************/
Std_ReturnType NvM_QueuePush(
    NvM_BlockIdType BlockId,
    NvM_JobIdType JobId,
    NvMRamBlockDataAddressType RamAddress
)
{
    Std_ReturnType retVal = E_NOT_OK;

    NvM_QueueIndexType queueIndex = 0u;

    for(queueIndex = 0u; queueIndex < NVM_SIZE_JOB_QUEUE; queueIndex++)
    {
        CurrentQueue = (NvM_QueueType*)&NvM_JobQueueTable[CurrentQueue->NextEntry];
        if(SET == CurrentQueue->QueueEmpty)
        {
            CurrentQueue->BlockId = BlockId;
            CurrentQueue->JobId = JobId;
            CurrentQueue->RamAddress = RamAddress;
            CurrentQueue->QueueEmpty = RESET;
            
            retVal = E_OK;
            break;
        }
    }

    return(retVal);
}


/*******************************************************************************
* -Name            NvM_UnEmptyQueue
* -Brief           Get un-empty queue
* -Details         None
* -Param[in]       BlockId: The block identifier uniquely identifies one NVRAM block descriptor
* -Param[in]       JobId: Job Id
* -Param[in]       RamAddress: RamAddress
* -Return          None          
*******************************************************************************/
Std_ReturnType NvM_QueuePop(
    NvM_QueueType* Queue
)
{
    Std_ReturnType retVal = E_NOT_OK;

    NvM_QueueIndexType queueIndex = 0u;

    for(queueIndex = 0u; queueIndex < NVM_SIZE_JOB_QUEUE; queueIndex++)
    {
        CurrentQueue = (NvM_QueueType*)&NvM_JobQueueTable[CurrentQueue->NextEntry];
        if(RESET == CurrentQueue->QueueEmpty)
        {
            memcpy((uint8 *)(Queue), (uint8 *)(CurrentQueue), sizeof(NvM_QueueType));
            CurrentQueue->QueueEmpty = SET;
            retVal = E_OK;
            break;
        }
    }
    
    return(retVal);
}

